package com.leenmvc.core.dao.iotdb;

import com.leenmvc.core.dao.iotdb.connect.IOTdbConnectionFactory;
import com.leenmvc.core.dao.iotdb.domain.TimeseriesDomain;
import com.leenmvc.core.dao.iotdb.util.IotDbUtil;
import com.leenmvc.core.exception.BusinessException;
import com.leenmvc.core.utils.DateUtils;
import com.leenmvc.core.utils.StringUtils;
import org.apache.iotdb.jdbc.IoTDBSQLException;
import org.apache.iotdb.rpc.IoTDBConnectionException;
import org.apache.iotdb.rpc.StatementExecutionException;
import org.apache.iotdb.session.pool.SessionDataSetWrapper;
import org.apache.iotdb.session.pool.SessionPool;
import org.apache.iotdb.tsfile.file.metadata.enums.CompressionType;
import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding;
import org.apache.iotdb.tsfile.read.common.Field;
import org.apache.iotdb.tsfile.read.common.RowRecord;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.Serializable;
import java.sql.*;
import java.util.*;

@Component
public class IotDBDaoImp implements IotDBDao, Serializable {

    private final static Logger logger = LoggerFactory.getLogger(IotDBDaoImp.class);

    private static IotDBDaoImp baseDao = null;

    public synchronized static IotDBDaoImp getInstance() {
        if (baseDao == null) {
            baseDao = new IotDBDaoImp();
        }
        return baseDao;
    }

    @Autowired
    private SessionPool sessionPool;

    @Override
    public void setStorageGroup(String storageGroupName) {
        if (null == storageGroupName) {
            throw new BusinessException("存储组名称不能为空");
        }
        if (validateStorageGroup(storageGroupName)) {
            throw new BusinessException("该存储组已经存在："+ storageGroupName);
        }
        try {
            sessionPool.setStorageGroup(storageGroupName);
        } catch (IoTDBConnectionException e) {
            logger.error(e.getMessage(), e);
        } catch (StatementExecutionException e) {
            logger.error(e.getMessage(), e);
        }
    }


    @Override
    public void createTimeseries(String storageGroup,TimeseriesDomain timeseriesDomain, Long deviceId) {
        // 序列全路径名
        String url = storageGroup + "." + deviceId + "."+timeseriesDomain.getName();
        try {
            TSDataType dataType = IotDbUtil.dataTypeChange(timeseriesDomain.getDataType());
            //验证该时间序列是否已创建 ,存在创建失败
            if (sessionPool.checkTimeseriesExists(url)){
                // 如果已经存在，需要判断类型是否一致
                String timeseriesDadaType = getTimeseriesDadaType(url);
                TSDataType oldTsDataType = TSDataType.valueOf(timeseriesDadaType);
                if (dataType == oldTsDataType){
                    // 如果类型相等不做处理，相当于创建测点成功
                    return;
                }else {
                    // 如果类型不一致，需要先删除之前的测点!先删除再从新创建
                    sessionPool.deleteTimeseries(url);
                }
            }
            sessionPool.createTimeseries(url,dataType,IotDbUtil.optionTSEncoding(dataType),CompressionType.SNAPPY);
        } catch (IoTDBConnectionException e) {
            logger.error(e.getMessage(), e);
        } catch (StatementExecutionException e) {
            logger.error(e.getMessage(), e);
        }
    }

    @Override
    public void batchCreateTimeseries(String storageGroup,List<TimeseriesDomain> timeseriesDomains, Long deviceId) {
        // 序列全路径名
        List<String> paths = new ArrayList<>();
        List<TSDataType> dataTypes = new ArrayList<>();
        List<TSEncoding> encodings = new ArrayList<>();
        List<CompressionType> compressors = new ArrayList<>();
        String url = null;
        try {
            for (TimeseriesDomain domain : timeseriesDomains) {
                TSDataType tsDataType = IotDbUtil.dataTypeChange(domain.getDataType());
                url = storageGroup + "." + deviceId + "."+domain.getName();
                // 先判断是否存在
                if (sessionPool.checkTimeseriesExists(url)){
                    // 如果已经存在，需要判断类型是否一致
                    String timeseriesDadaType = getTimeseriesDadaType(url);
                    TSDataType oldTsDataType = TSDataType.valueOf(timeseriesDadaType);
                    if (tsDataType == oldTsDataType){
                        // 如果类型相等不做处理，相当于创建测点成功
                        continue;
                    }else {
                        // 如果类型不一致，需要先删除之前的测点!先删除再从新创建
                        sessionPool.deleteTimeseries(url);
                    }
                }
                paths.add(url);
                dataTypes.add(tsDataType);
                encodings.add(IotDbUtil.optionTSEncoding(tsDataType));
                compressors.add(CompressionType.SNAPPY);
            }
            if (paths.size() == 0 || dataTypes.size() == 0 || encodings.size() == 0 || compressors.size() == 0){
                return;
            }
            sessionPool.createMultiTimeseries(paths,dataTypes,encodings,compressors,null,null,null,null);
        } catch (IoTDBConnectionException e) {
            logger.error(e.getMessage(), e);
        } catch (StatementExecutionException e) {
            logger.error(e.getMessage(), e);
        }
    }

    public String getTimeseriesDadaType(String timeseriesPath){
        StringBuilder sql = new StringBuilder("SHOW TIMESERIES ").append(timeseriesPath);
        SessionDataSetWrapper dataSetWrapper = null;
        String value = null;
        try {
            dataSetWrapper = sessionPool.executeQueryStatement(String.valueOf(sql));
            while (dataSetWrapper.hasNext()){
                RowRecord next = dataSetWrapper.next();
                List<org.apache.iotdb.tsfile.read.common.Field> fields = next.getFields();
                value = (String) IotDbUtil.getValue(fields.get(3));
            }
        } catch (IoTDBConnectionException e) {
            logger.error(e.getMessage(), e);
        } catch (StatementExecutionException e) {
            logger.error(e.getMessage(), e);
        }finally {
            sessionPool.closeResultSet(dataSetWrapper);
        }
        return value;
    }

    @Override
    public void insert(String groupName, Long deviceId, long time, Map<String,Object> map){
        String url = groupName+ "."+ deviceId;
        List<String> measurements = new ArrayList<>();
        // 需要服务器做类型判断
        List<String> values = new ArrayList<>();
        for (String key : map.keySet()) {
            measurements.add(key);
            values.add(String.valueOf(map.get(key)));
        }
        try {
            sessionPool.insertRecord(url,time,measurements,values);
        } catch (IoTDBConnectionException e) {
            logger.error(e.getMessage(), e);
        } catch (StatementExecutionException e) {
            logger.error(e.getMessage(), e);
        }

    }

    @Override
    public void insert(String groupName, Long deviceId, long time, List<TimeseriesDomain> list) {
        String url = groupName+ "."+ deviceId;
        if (list.isEmpty()){
            throw new BusinessException("参数不能为空");
        }
        List<String> measurements = new ArrayList<>();
        List<Object> values = new ArrayList<>();
        List<TSDataType> dataTypes = new ArrayList<>();
        list.forEach(timeseriesDomain -> {
            measurements.add(timeseriesDomain.getName());
            dataTypes.add(IotDbUtil.dataTypeChange(timeseriesDomain.getDataType()));
            values.add(timeseriesDomain.getValue());
        });
        try {
            sessionPool.insertRecord(url,time,measurements,dataTypes,values);
        } catch (IoTDBConnectionException e) {
            logger.error(e.getMessage(), e);
        } catch (StatementExecutionException e) {
            logger.error(e.getMessage(), e);
        }
    }

    @Override
    public void batchInset(String groupName, List<String> deviceIds, long time, List<Map<String, String>> maps) {
        String url = null;
        List<List<String>> measurementsList = new ArrayList<>();
        List<Long> times = new ArrayList<>();
        List<List<String>> valuesList = new ArrayList<>();
        List<String> urls = new ArrayList<>();

        List<String> measurements = new ArrayList<>();
        List<String> values = new ArrayList<>();
        for (int i = 0; i < deviceIds.size() ; i++) {
            url = groupName+ "."+ deviceIds.get(i);
            urls.add(url);
            times.add(time);
            Map<String, String> stringStringMap = maps.get(i);
            for (String key : stringStringMap.keySet()) {
                measurements.add(key);
                values.add(stringStringMap.get(key));
            }
            measurementsList.add(measurements);
            valuesList.add(values);
            measurements.clear();
            values.clear();
        }
        try {
            sessionPool.insertRecords(urls,times,measurementsList,valuesList);
        } catch (IoTDBConnectionException e) {
            logger.error(e.getMessage(), e);
        } catch (StatementExecutionException e) {
            logger.error(e.getMessage(), e);
        }
    }



//    @Override
//    public Boolean saveTimeseriesBatch(List<TimeseriesDomain> timeseriesDomains, String deviceId) {
//
////        Boolean flag = false;
////        for (TimeseriesDomain domain : timeseriesDomains) {
////            flag = createTimeseries(domain, deviceId);
////        }
////        return flag;
//    }

//    @Override
//    public List<Map<String, Object>> getDataByDeviceId(String deviceId) {
//        StringBuffer sql = new StringBuffer("select * from root." + deviceId);
//        List<Map<String, Object>> maps = executeQuery(sql.toString(), true, "");
//        return maps;
//    }

//    @Override
//    public List<TimeseriesDomain> getTimeseriesByDeviceId(StFring deviceId) {
//        return null;
//    }

//    @Override
//    public List<TimeseriesDomain> getTimeseriesByDeviceId(String deviceId) {
//
//        StringBuffer sql = new StringBuffer("show timeseries root." + deviceId);
//        Connection connection = IOTdbConnectionFactory.getConnection();
//        PreparedStatement preparedStatement = null;
//        ResultSet resultSet = null;
//        List<Map<String, Object>> maps = null;
//        List<TimeseriesDomain> domains = null;
//        try {
//            preparedStatement = connection.prepareStatement(sql.toString());
//            preparedStatement.execute();
//            resultSet = preparedStatement.getResultSet();
////            maps = resultSetToMap(resultSet, false);
//            domains = resultSetToTimeseries(resultSet);
//        } catch (SQLException e) {
//            logger.info(e.getMessage(), e);
//        } finally {
//            IOTdbConnectionFactory.closeConnection(connection);
//        }
//        return domains;
//    }

    @Override
    public List<org.apache.iotdb.tsfile.read.common.Field> showStorageGroup() {
        StringBuffer sql = new StringBuffer("show storage group");
        SessionDataSetWrapper dataSetWrapper = null;
        List<org.apache.iotdb.tsfile.read.common.Field> fields = null;
        try {
            logger.info("正在执行IOTDB的SQL语句: {}", sql.toString());
            dataSetWrapper = sessionPool.executeQueryStatement(sql.toString());
            while (dataSetWrapper.hasNext()){
                RowRecord rowRecord = dataSetWrapper.next();
                fields = rowRecord.getFields();
            }
        } catch (StatementExecutionException e) {
            logger.error(e.getMessage(), e);
        } catch (IoTDBConnectionException e) {
            logger.error(e.getMessage(), e);
        } finally {
            sessionPool.closeResultSet(dataSetWrapper);
        }
        return fields;
    }

//    @Override
//    public Boolean save(String deviceId, JSONObject dataJson) {
//        if (null == dataJson) {
//            return false;
//        }
//        StringBuffer sql = new StringBuffer("insert into root." + deviceId + " (timestamp,");
//        for (Map.Entry<String, Object> entry : dataJson.entrySet()) {
//            if (!entry.getKey().equals("t")) {
//                sql.append(entry.getKey() + ",");
//            }
//        }
//        sql = new StringBuffer(sql.toString().substring(0, sql.length() - 1));
//        sql.append(") values (");
////        sql.append(String.valueOf(dataJson.get("create_time")) + ",");
//        sql.append(System.currentTimeMillis() + ",");
//        for (Map.Entry<String, Object> entry : dataJson.entrySet()) {
//            if (!entry.getKey().equals("t")) {
//                sql.append("?,");
//            }
//        }
//
//        sql = new StringBuffer(sql.toString().substring(0, sql.length() - 1)).append(")");
//        Connection connection = IOTdbConnectionFactory.getConnection();
//        logger.info("获取IOTDB连接成功");
//        PreparedStatement preparedStatement = null;
//        boolean execute = false;
//        try {
//            preparedStatement = connection.prepareStatement(sql.toString());
//            int num = 1;
//            for (Map.Entry<String, Object> entry : dataJson.entrySet()) {
//                if (!entry.getKey().equals("t")) {
//                    if (entry.getValue() instanceof BigDecimal || StringUtils.isFloatNumber(entry.getValue().toString()) || entry.getValue() instanceof Float) {
//                        preparedStatement.setFloat(num, Float.valueOf(String.valueOf(entry.getValue())));
//                    } else {
//                        preparedStatement.setObject(num, entry.getValue());
//                    }
//                    num++;
//                }
//            }
//            logger.info("正在执行IOTdb的SQL： {}", sql.toString());
//            execute = preparedStatement.execute();
//        } catch (SQLException e) {
//            logger.error(e.getMessage(), e);
//        } finally {
//            IOTdbConnectionFactory.closeConnection(connection);
//        }
//        return execute;
//    }

//    @Override
//    public List<TimeseriesDomain> getTimeseries(String deviceId, Wrapper wrapper) {
//        return null;
//    }

//    @Override
//    public List<TimeseriesDomain> getTimeseries(String deviceId, Wrapper wrapper) {
//        List<TimeseriesDomain> timeseries = getTimeseriesByDeviceId(deviceId);
//        StringBuffer sql = new StringBuffer("select ");
//        for (TimeseriesDomain timeseriesDomain : timeseries) {
//            String timeseriesName = String.valueOf(timeseriesDomain.getName());
//            String timeName = StringUtils.getLastString(timeseriesName);
//            sql.append(timeName + ",");
//        }
//        String substring = sql.substring(0, sql.length() - 1);
//        sql = new StringBuffer(substring);
//        sql.append(" from root." + deviceId)
//                .append(" where ")
//                .append(wrapper.getWhere());
//        Connection connection = IOTdbConnectionFactory.getConnection();
//        PreparedStatement preparedStatement;
//        ResultSet resultSet;
//        List<TimeseriesDomain> timeseriesDomains = null;
//        try {
//            logger.info("正在执行IOTDB的sql语句:{}" , sql.toString());
//            preparedStatement = connection.prepareStatement(sql.toString());
//            int num = 1;
//            for (Object o : wrapper.getParamList()) {
//                preparedStatement.setObject(num, o);
//                num++;
//            }
//            preparedStatement.executeQuery();
//            resultSet = preparedStatement.getResultSet();
//            timeseriesDomains = resultSetToTimeseries(resultSet);
//        } catch (SQLException e) {
//            logger.error(e.getMessage(), e);
//        } finally {
//            IOTdbConnectionFactory.closeConnection(connection);
//        }
//        return timeseriesDomains;
//    }

//    @Override
//    public List<Map<String, Object>> getCount(BaseIotWrapper iotWrapper) {
//        StringBuffer sql = new StringBuffer("select ");
//        List<String> timeseries = iotWrapper.getTimeseries();
//        for (String timesery : timeseries) {
//            sql.append("count(");
//            sql.append(timesery + "),");
//        }
//        sql = new StringBuffer(sql.substring(0, sql.length() - 1));
//        sql.append(" from root." + iotWrapper.getDeviceId());
//        StringBuffer where = iotWrapper.getWhere();
//        sql.append(" where " + where);
//        Connection connection = IOTdbConnectionFactory.getConnection();
//        PreparedStatement preparedStatement = null;
//        ResultSet resultSet = null;
//        List<Map<String, Object>> maps = null;
//        try {
//            preparedStatement = connection.prepareStatement(sql.toString());
//            resultSet = preparedStatement.executeQuery();
//            maps = resultSetToMap(resultSet, true);
//        } catch (SQLException e) {
//            logger.error(e.getMessage(), e);
//        } finally {
//            IOTdbConnectionFactory.closeConnection(connection);
//        }
//        return maps;
//    }

//    @Override
//    public List<Map<String, Object>> getMaxValue(String deviceId, String timeseriesName) {
//        return null;
//    }

//    @Override
//    public List<Map<String, Object>> getMinValue(String deviceId, String timeseriesName) {
//        return null;
//    }

//    @Override
//    public List<Map<String, Object>> getMinTime(String deviceId, String timeseriesName) {
//        return null;
//    }

//    @Override
//    public List<Map<String, Object>> getMaxTime(String deviceId, String timeseriesName) {
//        return null;
//    }

//    @Override
//    public List<Map<String, Object>> getDataByWrapper(IotQueryWrapper wrapper) {
//        StringBuffer sql = wrapper.getSql();
//        return executeQuery(sql.toString(), true, "");
//    }
//
//
//
//    @Override
//    public List getDataByWrapper(IotQueryWrapper wrapper, Class<?> clz) {
//        StringBuffer sql = wrapper.getSql();
//        List<Map<String, Object>> list = executeQuery(sql.toString(), true, "");
//        List tList = mapToEntity(list, clz);
//        return tList;
//    }

//    /**
//     * 根据返回的ListMap<> 封装成所对应的实体
//     *
//     * @param list
//     * @param clz
//     * @return
//     */
//    private List mapToEntity(List<Map<String, Object>> list, Class<?> clz) {
//        List resultList = new ArrayList<>();
//        for (Map<String, Object> map : list) {
//            Object o = null;
//            try {
//                o = clz.newInstance();
//                Field[] fields = clz.getDeclaredFields();
//                for (Field field : fields) {
//                    for (Map.Entry<String, Object> entry : map.entrySet()) {
//                        Method setMethod = ClassUtil.getSetMethod(field);
//                        if (field.getName().equals("time") && "Time".equals(StringUtils.getLastString(entry.getKey()))) {
////                            java.util.Date parse = DateUtils.parse(String.valueOf(entry.getValue()));
////                            String time = DateUtils.format(parse);
//                            setMethod.invoke(o, entry.getValue());
//                            break;
//                        }
//                        if (field.getName().equals(StringUtils.getLastString(entry.getKey()))) {
//                            setMethod.invoke(o, entry.getValue());
//                            break;
//                        }
//                    }
//                }
//            } catch (InstantiationException e) {
//                logger.error(e.getMessage(), e);
//            } catch (IllegalAccessException e) {
//                logger.error(e.getMessage(), e);
//            } catch (InvocationTargetException e) {
//                logger.error(e.getMessage(), e);
//            }
//            resultList.add(o);
//        }
//        return resultList;
//    }

    @Override
    public Map<String,Object> getLastData(String groupName, Long deviceId, Set<String> params){
        String join = StringUtils.join(params, ",");
        StringBuilder sql = new StringBuilder("select last ");
        sql.append(join)
                .append(" from ")
                .append(groupName)
                .append(".")
                .append(deviceId);
        HashMap<String, Object> resultMap = new HashMap<>();
        try {
            logger.info("sql:{}",sql);
            SessionDataSetWrapper dataSetWrapper = sessionPool.executeQueryStatement(sql.toString());
            while (dataSetWrapper.hasNext()){
                RowRecord rowRecord = dataSetWrapper.next();
                List<org.apache.iotdb.tsfile.read.common.Field> fields = rowRecord.getFields();
                String key = (String) IotDbUtil.getValue(fields.get(0));
                Object value =  IotDbUtil.getValue(fields.get(1));
                resultMap.put(key.substring(key.lastIndexOf(".")+1),value);
            }
        } catch (IoTDBConnectionException e) {
            logger.error(e.getMessage(), e);
        } catch (StatementExecutionException e) {
            logger.error(e.getMessage(), e);
        }
        return resultMap;
    }

    @Override
    public Object getFirstOrLastValue(String groupName, Long deviceId, String filedName, long startTime, long endTime,boolean isLast) {
        String url = groupName + "." + deviceId;
        StringBuilder sql = new StringBuilder("select ");
        if (isLast){
            sql.append("LAST_VALUE(");
        }else {
            sql.append("FIRST_VALUE(");
        }
                sql.append(filedName)
                .append(")")
                .append(" from ")
                .append(url)
                .append(" where ")
                .append("time > ")
                .append(startTime)
                .append(" and time < ")
                .append(endTime);
        logger.info("sql:{}",sql);
        Object result = null;
        try {
            SessionDataSetWrapper sessionDataSetWrapper = sessionPool.executeQueryStatement(sql.toString());
            while (sessionDataSetWrapper.hasNext()){
                RowRecord rowRecord = sessionDataSetWrapper.next();
                List<org.apache.iotdb.tsfile.read.common.Field> fields = rowRecord.getFields();
                Field field = fields.get(0);
                if (field.getDataType() == null){
                    result = null;
                }else {
                    result =  IotDbUtil.getValue(fields.get(0));
                }
            }
        } catch (IoTDBConnectionException e) {
            e.printStackTrace();
        } catch (StatementExecutionException e) {
            e.printStackTrace();
        }
        return result;
    }

//    @Override
//    public List<Map<String, Object>> getBySql(String sql) {
//        return executeQuery(sql, true, "");
//
//    }

//    @Override
//    public Map<String, Object> getLastData(String deviceId) {
//        StringBuffer sql = new StringBuffer("select last ");
////        List<TimeseriesDomain> timeseries = getTimeseriesByDeviceId(deviceId);
////        if (timeseries.size()<=0){
//         return null;
//        }
//        for (TimeseriesDomain timesery : timeseries) {
//            if (null != timesery.getName()) {
//                sql.append(timesery.getName()).append(",");
//            }
//        }
//        sql = new StringBuffer(sql.toString().substring(0, sql.length() - 1));
//        sql.append(" from root." + deviceId);
//        List<Map<String, Object>> maps = executeQuery(sql.toString(), true, "last");
//        if (maps.size() != 1) {
//            throw new BusinessException("查询数据失败");
//        }
//        Map<String, Object> map = maps.get(0);
//        map.put("id", deviceId.split("\\.")[1]);
//        return map;

//    }

    /**
     * 把查询结果集封装成List<Map>
     *
     * @param resultSet 结果集
     * @param isChange  是否需要把Time属性转换为日期类型
     * @return
     *
     */
    public List<Map<String, Object>> resultSetToMap(ResultSet resultSet, Boolean isChange) {
        if (null == resultSet) {
            return null;
        }
        ResultSetMetaData metaData;
        List<Map<String, Object>> maps = new ArrayList<>();
        int columnCount;
        try {
            metaData = resultSet.getMetaData();
            Map<String, Object> map;
            columnCount = metaData.getColumnCount();
            while (resultSet.next()) {
                map = new HashMap<>();
                for (int i = 1; i <= columnCount; i++) {
                    String columnLabel = metaData.getColumnLabel(i);
                    String columnValue = resultSet.getString(i);
                    if (isChange && "Time".equals(columnLabel)) {
                        map.put(columnLabel, DateUtils.getDate(Long.valueOf(columnValue)));
                    } else {
                        map.put(columnLabel, columnValue);
                    }
                }
                maps.add(map);
            }
        } catch (SQLException e) {
            logger.error(e.getMessage(), e);
        }
        return maps;
    }

    /**
     * 把查询结果集封装成List<Map>(Last查询方式)
     *
     * @param resultSet 结果集
     * @param isChange  是否需要把Time属性转换为日期类型
     * @return
     */
    public Map<String, Object> resultSetToMapForLast(ResultSet resultSet, Boolean isChange) {
        if (null == resultSet) {
            return null;
        }
        ResultSetMetaData metaData;
        Map<String, Object> map = new HashMap<>();
        try {
            while (resultSet.next()) {
                String time = resultSet.getString(1);
                map.put("time", DateUtils.getDate(Long.valueOf(time)));
                String columnLabel = resultSet.getString(2);
//                String columnValue = resultSet.getString(3);
                Object columnValue = resultSet.getObject(3);
                String[] split = columnLabel.split("\\.");
                String key = split[split.length - 1];
                if ("create_time".equals(key)) {
                    map.put(key, DateUtils.getDate(Long.valueOf(resultSet.getString(1))));
                } else {
                    map.put(key, columnValue);
                }
            }
        } catch (SQLException e) {
            logger.error(e.getMessage(), e);
        }
        return map;
    }

    /**
     * 把返回回来的时间序列转换为pojo
     *
     * @param resultSet
     * @return
     */
//    public List<TimeseriesDomain> resultSetToTimeseries(ResultSet resultSet) {
//        if (null == resultSet) {
//            return null;
//        }
//        ResultSetMetaData metaData;
//        List<TimeseriesDomain> timeseriesDomains = new ArrayList<>();
//        int columnCount;
//        try {
//            metaData = resultSet.getMetaData();
//            columnCount = metaData.getColumnCount();
//            while (resultSet.next()) {
//                TimeseriesDomain domain = new TimeseriesDomain();
//                for (int i = 1; i <= columnCount; i++) {
//                    String columnLabel = metaData.getColumnLabel(i);
//                    String columnValue = resultSet.getString(i);
//                    switch (columnLabel) {
//                        case "timeseries":
//                            domain.setName(StringUtils.getLastString(columnValue));
//                            break;
//                        case "storage group":
//                            domain.setStorageGroup(columnValue);
//                            break;
//                        case "dataType":
//                            domain.setDataType(columnValue);
//                            break;
//                        case "encoding":
//                            domain.setEncoding(columnValue);
//                            break;
//                        default:
//                            break;
//                    }
//                }
//                timeseriesDomains.add(domain);
//            }
//        } catch (SQLException e) {
//            logger.error(e.getMessage(), e);
//        }
//        return timeseriesDomains;
//    }


    /**
     * 验证前面传过来的时间序列在时序数据库是否已存在
     *
     * @param timeseriesDomain 传过来的单个时间序列
     * @param deviceId         deviceId
     * @return
     */
//    public Boolean validateTimeseries(TimeseriesDomain timeseriesDomain, String deviceId) {
//        Boolean flag = false;
//        List<TimeseriesDomain> timeseries = getTimeseriesByDeviceId(deviceId);
//        for (TimeseriesDomain timesery : timeseries) {
//            String timesValue = String.valueOf(timesery.getName());
//            String[] split = timesValue.split("\\.");
//            for (String s : split) {
//                if (timesValue != null && timeseriesDomain.getName().equals(s)) {
//                    flag = true;
//                }
//            }
//        }
//        return flag;
//    }


    /**
     * 根据deviceId验证该存储过程有没有被创建
     *
     * @param storageGroupName
     * @return
     */
    public Boolean validateStorageGroup(String storageGroupName) {
        if (null == storageGroupName) {
            return false;
        }
        Boolean flag = false;
        List<org.apache.iotdb.tsfile.read.common.Field> fields = showStorageGroup();
        if (fields == null ){
            return false;
        }
        for (org.apache.iotdb.tsfile.read.common.Field field : fields){
            String value = (String) IotDbUtil.getValue(field);
            if (null != storageGroupName && storageGroupName.equals(value)){
                flag = true;
                break;
            }
        }
        return flag;
    }

    /**
     * 执行查询sql
     *
     * @param sql
     * @param queryType 查询方式 last 最新等
     * @return 查询结果
     */
    List<Map<String, Object>> executeQuery(String sql, Boolean isChange, String queryType) {
        if (null == sql) {
            return null;
        }
        Connection connection = IOTdbConnectionFactory.getConnection();
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        List<Map<String, Object>> maps = null;
        try {
            logger.info("正在执行IOTDB的sql语句：{}", sql);
            preparedStatement = connection.prepareStatement(sql);
            resultSet = preparedStatement.executeQuery();
            if ("last".equals(queryType)) {
                Map<String, Object> map = resultSetToMapForLast(resultSet, isChange);
                maps = new ArrayList<>();
                maps.add(map);
            } else {
                maps = resultSetToMap(resultSet, isChange);
            }
        } catch (IoTDBSQLException e) {
            logger.error(e.getMessage(), e);
            throw new BusinessException("查询的SQL语句格式错误或者该SQL语句不是查询语句");
        } catch (SQLException e) {
            logger.error(e.getMessage(), e);
        } finally {
            IOTdbConnectionFactory.closeConnection(connection);
        }
        return maps;
    }


}
